package com.atguigu.gmall.order.config;

import com.atguigu.gmall.common.constant.MqConst;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @Description
 * @Return
 * @Author https://weiranyi.github.io
 * @Date Created in 2022-12-23 08:48
 **/
@Configuration
public class MqConfig {
    /**
     * 1. 交换机器
     * 方式一：springboot启动看到MQ没有的时候就会自动创建被@Bean标注的交换机&队列
     * 方式二：借助AmqpAdmin创建交换机
     * AmqpAdmin amqpAdmin;
     * public void test(){
     * amqpAdmin.declareExchange();
     * amqpAdmin.declareQueue();
     * amqpAdmin.declareBinding();
     * }
     */
    // 订单事件交换机
    @Bean
    public Exchange orderEventExchange() {
        // (String name, boolean durable, boolean autoDelete, Map<String, Object> arguments[交换机的参数设置项])
        return new TopicExchange(MqConst.ORDER_EVENT_EXCHANGE, true, false, null);
    }

    // 2.订单队列之-延迟队列
    @Bean
    public Queue orderDelayQueue() {
        /**
         * (String name, boolean durable,
         * boolean exclusive,  排他，这里关闭排他，这样可以同时多个微服务消费队列，避免单点故障；开启排他就穿行化能保证业务顺序
         * boolean autoDelete, 自动删除
         * @Nullable Map<String, Object> arguments) 参数设置项
         */
        Map<String, Object> arguments = new HashMap<>();
        // 将MqConst.ORDER_EVENT_EXCHANGE作为死信交换机
        arguments.put(MqConst.X_DEAD_LATTER_EXCHANGE, MqConst.ORDER_EVENT_EXCHANGE);
        arguments.put(MqConst.X_DEAD_LATTER_ROUTING_KEY, MqConst.ORDER_TIMEOUT_RK);
        arguments.put(MqConst.X_MESSAGE_TTL, MqConst.ORDER_TTL);


        return new Queue(MqConst.ORDER_DELAY_QUEUE, true, false, false, arguments);
    }

    // 3.订单队列之-死信队列
    @Bean
    public Queue orderDeadQueue() {
        return new Queue(MqConst.ORDER_DEAD_QUEUE, true, false, false, null);
    }

    // 4.绑定关系
    @Bean
    public Binding delayBinding() {
        /**
         * (String destination, 目的地
         * DestinationType destinationType, 目的地类型（交换机还是队列）
         * String exchange, String routingKey,
         * @Nullable Map<String, Object> arguments)
         * 把 exchange 和 destinationType类型的 destination目的地 用 routingKey 绑在一起
         */
        return new Binding(MqConst.ORDER_DELAY_QUEUE, Binding.DestinationType.QUEUE,
                MqConst.ORDER_EVENT_EXCHANGE, MqConst.ORDER_CREAT_RK, null);
    }

    @Bean
    public Binding deadBinding() {
        return new Binding(MqConst.ORDER_DEAD_QUEUE, Binding.DestinationType.QUEUE,
                MqConst.ORDER_EVENT_EXCHANGE, MqConst.ORDER_TIMEOUT_RK, null);
    }

    // 下单成功后-消息到成功队列
    @Bean
    public Queue orderPayedQueue() {
        return new Queue(MqConst.ORDER_PAYED_QUEUE, true, false, false, null);
    }

    @Bean
    public Binding payedBinding() {
        return new Binding(MqConst.ORDER_PAYED_QUEUE, Binding.DestinationType.QUEUE,
                MqConst.ORDER_EVENT_EXCHANGE, MqConst.ORDER_PAYED_RK, null);
    }
}
